package ec.linde.modulos.proyectos;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import org.primefaces.component.datatable.DataTable;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

import ec.linde.enumeraciones.Estado;
import ec.linde.modulos.proyectos.servicio.ServicioPlanillaContratista;
import ec.linde.modulos.proyectos.servicio.ServicioRdo;
import ec.linde.persistencia.entidades.proyectos.DetallePlanillaContratista;
import ec.linde.persistencia.entidades.proyectos.DetalleRdo;
import ec.linde.persistencia.entidades.proyectos.PlanillaContratista;
import ec.linde.persistencia.entidades.proyectos.Rdo;

/**
 * TODO: Agregar descripcion
 * 
 * @FechaCreacion: 29/03/2013
 * @author: Alex Carrillo
 * @FechaModificacion: 29/03/2013
 * @author: Alex Carrillo
 * @version: 1.0
 */
@ManagedBean
@ViewScoped
public class PlanillaContratistaBean extends PageController {

	private static final long serialVersionUID = 1L;

	/**
	 * Servicios
	 */
	@EJB
	private ServicioPlanillaContratista servicioPlanillaContratista;
	@EJB
	private ServicioRdo servicioRdo;

	/**
	 * Atributos Forma
	 */
	private PlanillaContratista planillaContratista;
	private DetallePlanillaContratista detallePlanillaContratistaSeleccionado;
	private Integer idRdo;

	/**
	 * Listados 1. Lista Lazy DataModel 2. Lista Detalles 3. Listas Combo
	 */
	private LazyDataModel<PlanillaContratista> listaPlanillaContratista;
	private List<DetallePlanillaContratista> listaDetallePlanillaContratista;
	/**
	 * UI
	 */
	private DataTable dtPlanillaContratista;
	private DataTable dtDetallePlanillaContratista;
	private DataTable dtCronogramaPlanillaContratista;

	/**
	 * PostContrutor
	 */
	@PostConstruct
	public void init() {

		listaPlanillaContratista = new LazyDataModel<PlanillaContratista>() {

			private static final long serialVersionUID = 1L;

			@Override
			public List<PlanillaContratista> load(int startIndex, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
				List<PlanillaContratista> lista = new ArrayList<PlanillaContratista>();

				boolean ordenar = sortOrder == SortOrder.ASCENDING ? true : false;
				lista = servicioPlanillaContratista.obtenerListaPorPagina(startIndex, pageSize, sortField, ordenar, filters);

				listaPlanillaContratista.setRowCount(servicioPlanillaContratista.contarPorCriterio(filters));

				return lista;
			}
		};

	}

	/**
	 * Metodos
	 */

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#editar()
	 */
	public String editar() {
		addInfoMessage("Accion no permitida");
		return "";
	}

	/*
	 * (non-Javadoc)\
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#guardar()
	 */
	public String guardar() {
		try {
			if (validar()) {
				servicioPlanillaContratista.guardar(planillaContratista);
				addInfoMessage("Registro Guardado Correctamente");
				setEditado(false);
				limpiar();
				return "planillaContratista.xhtml?faces-redirect=true";
			} else {
				return "";
			}
		} catch (Exception e) {
			addErrorMessage("Error al Guardar el registro");
		}
		return "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#eliminar()
	 */
	public String eliminar() {
		return "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#limpiar()
	 */
	@Override
	public String limpiar() {
		planillaContratista = null;
		return "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ec.linde.modulos.proyectos.PageController#cancelar()
	 */
	@Override
	public String cancelar() {
		setEditado(false);
		limpiar();
		return "planillaContratista.xhtml?faces-redirect=true";
	}

	/**
	 * TODO: Agregar descripcion del metodo
	 * 
	 * @return
	 */
	public List<DetallePlanillaContratista> getListaDetallePlanillaContratista() {
		if (listaDetallePlanillaContratista == null) {
			listaDetallePlanillaContratista = new ArrayList<DetallePlanillaContratista>();
			for (DetallePlanillaContratista detallePlanillaContratista : planillaContratista.getListaDetallePlanillaContratista()) {
				if (!detallePlanillaContratista.isEliminado()) {
					listaDetallePlanillaContratista.add(detallePlanillaContratista);
				}
			}
		}
		return listaDetallePlanillaContratista;
	}

	/**
	 * Carga el plan operativo ya sea desde el proyecto o desde el ultimo plan operativo
	 */
	public void cargarPlanillaContratistaDesdeRdo() {

		if (idRdo != null && this.planillaContratista == null) {

			// Cargo el detalle del Plan Operativo Actual
			Rdo rdo = servicioRdo.cargarDetalle(idRdo);

			// Cargo el plan operativo
			HashMap<String, String> filters = new HashMap<String, String>();
			filters.put("rdo.idRdo", "" + rdo.getId());
			List<PlanillaContratista> lista = servicioPlanillaContratista.obtenerListaCombo("", true, filters);

			// Si la lista del planillaContratista no existe me crea un nuevo planillaContratista
			if (lista.isEmpty()) {

				this.planillaContratista = new PlanillaContratista();
				planillaContratista.setRdo(rdo);
				planillaContratista.setEstado(Estado.ELABORADO);
				planillaContratista.setFecha(new Date());
				for (DetalleRdo drdo : rdo.getListaDetalleRdo()) {

					DetallePlanillaContratista dplanillaContratista = new DetallePlanillaContratista();
					dplanillaContratista.setIdDetallePlanillaContratista(0);
					dplanillaContratista.setPlanillaContratista(planillaContratista);
					dplanillaContratista.setPartida(drdo.getPartida());
					dplanillaContratista.setConcepto(drdo.getConcepto());
					dplanillaContratista.setCosto(drdo.getCostoUnitario());
					dplanillaContratista.setCantidad(drdo.getCantidad());
					dplanillaContratista.setCantidadActual(drdo.getCantidad());
					dplanillaContratista.setCostoActual(drdo.getCostoUnitario());
					planillaContratista.getListaDetallePlanillaContratista().add(dplanillaContratista);

				}

			} else {

				if (lista.get(0).getEstado() == Estado.ELABORADO) {

					// Cargo el detalle del PlanillaContratista Actual y seto el plan operativo asl planillaContratista
					planillaContratista = servicioPlanillaContratista.cargarDetalle(lista.get(0).getId());
					planillaContratista.setRdo(rdo);

					// Se llena el hasmap de los detalles del planillaContratista actual y se eliminan
					HashMap<String, DetallePlanillaContratista> hmDPlanillaContratista = new HashMap<String, DetallePlanillaContratista>();
					for (DetallePlanillaContratista detallePlanillaContratista : planillaContratista.getListaDetallePlanillaContratista()) {
						hmDPlanillaContratista.put(detallePlanillaContratista.getPartida().getPadeId() + "~"
								+ detallePlanillaContratista.getConcepto().getConcId(), detallePlanillaContratista);
						detallePlanillaContratista.setEliminado(true);
					}

					// Se recorre el detalle del plan operativo para habilitar los registros que estan en el plan operativo y dar el orden al
					// planillaContratista del plan
					// operativo
					for (DetalleRdo drdo : rdo.getListaDetalleRdo()) {

						// Verifica si existe el detalle del planillaContratista y si existe lo activa caso contrario lo crea
						DetallePlanillaContratista detallePlanillaContratista = hmDPlanillaContratista.get(drdo.getPartida().getPadeId() + "~"
								+ drdo.getConcepto().getConcId());
						if (detallePlanillaContratista != null) {
							detallePlanillaContratista.setEliminado(false);
						} else {
							detallePlanillaContratista = new DetallePlanillaContratista();
							planillaContratista.getListaDetallePlanillaContratista().add(detallePlanillaContratista);
						}
						detallePlanillaContratista.setPlanillaContratista(planillaContratista);
						detallePlanillaContratista.setConcepto(drdo.getConcepto());
						detallePlanillaContratista.setCosto(drdo.getCostoUnitario());
						detallePlanillaContratista.setCantidad(drdo.getCantidad());
						detallePlanillaContratista.setCantidadActual(drdo.getCantidad());
						detallePlanillaContratista.setCantidadAnterior(servicioPlanillaContratista.cantidadPlanillaAnterior(rdo, drdo.getPartida(),
								drdo.getConcepto()));
						detallePlanillaContratista.setCostoActual(drdo.getCostoUnitario());
						detallePlanillaContratista.setCostoAnterior(servicioPlanillaContratista.costoPlanillaAnterior(rdo, drdo.getPartida(),
								drdo.getConcepto()));
					}

				} else {

					this.planillaContratista = new PlanillaContratista();
					planillaContratista.setRdo(rdo);
					planillaContratista.setEstado(Estado.ELABORADO);
					planillaContratista.setFecha(new Date());

					for (DetalleRdo drdo : rdo.getListaDetalleRdo()) {

						DetallePlanillaContratista dplanillaContratista = new DetallePlanillaContratista();
						dplanillaContratista.setIdDetallePlanillaContratista(0);
						dplanillaContratista.setPlanillaContratista(planillaContratista);
						dplanillaContratista.setPartida(drdo.getPartida());
						dplanillaContratista.setConcepto(drdo.getConcepto());
						dplanillaContratista.setCosto(drdo.getCostoUnitario());
						dplanillaContratista.setCantidad(drdo.getCantidad());
						dplanillaContratista.setCantidadActual(drdo.getCantidad());
						dplanillaContratista.setCantidadAnterior(servicioPlanillaContratista.cantidadPlanillaAnterior(rdo, drdo.getPartida(),
								drdo.getConcepto()));
						dplanillaContratista.setCostoActual(drdo.getCostoUnitario());
						dplanillaContratista.setCostoAnterior(servicioPlanillaContratista.costoPlanillaAnterior(rdo, drdo.getPartida(),
								drdo.getConcepto()));
						planillaContratista.getListaDetallePlanillaContratista().add(dplanillaContratista);

					}

				}
			}
			totalizar();
			setEditado(true);
		}

	}

	/**
	 * Aprueba el plan operativo
	 */
	public void aprobar() {
		if (planillaContratista != null) {
			if (planillaContratista.getEstado() == Estado.ELABORADO) {

				if (validarAprobacion(planillaContratista)) {
					servicioPlanillaContratista.cambiarEstado(planillaContratista.getId(), Estado.APROBADO);
					addInfoMessage("El registro se ha aprobado correctamente");
				}

			} else {
				addInfoMessage("Solo los planos operativos elaborados pueden ser aprobados");
			}

		} else {
			addInfoMessage("Seleccione un Registro");
		}

	}

	private boolean validarAprobacion(PlanillaContratista planillaContratista) {
		return false;
	}

	/**
	 * Totaliza los valores del plan operativo
	 */
	public void totalizar() {
		servicioPlanillaContratista.totalizar(planillaContratista);
	}

	/**
	 * VAlida el plan opertaivo antes de guardar
	 * 
	 * @return
	 */
	private boolean validar() {
		boolean resultado = true;
		return resultado;
	}

	/**
	 * Metodos Eventos
	 */

	/**
	 * Metodos GET Y SET
	 */

	/**
	 * Get del atributo planillaContratista
	 * 
	 * @return el valor del atributo planillaContratista
	 */
	public PlanillaContratista getPlanillaContratista() {
		return planillaContratista;
	}

	/**
	 * Set del atributo planillaContratista
	 * 
	 * @param proyecto
	 *            valor para asignar al atributo planillaContratista
	 */
	public void setPlanillaContratista(PlanillaContratista planillaContratista) {
		this.planillaContratista = planillaContratista;
	}

	/**
	 * Get del atributo idRdo
	 * 
	 * @return el valor del atributo idRdo
	 */
	public Integer getIdRdo() {
		return idRdo;
	}

	/**
	 * Set del atributo idRdo
	 * 
	 * @param idRdo
	 *            valor para asignar al atributo idRdo
	 */
	public void setIdRdo(Integer idRdo) {
		this.idRdo = idRdo;
	}

	public DetallePlanillaContratista getDetallePlanillaContratistaSeleccionado() {
		return detallePlanillaContratistaSeleccionado;
	}

	public void setDetallePlanillaContratistaSeleccionado(DetallePlanillaContratista detallePlanillaContratistaSeleccionado) {
		this.detallePlanillaContratistaSeleccionado = detallePlanillaContratistaSeleccionado;
	}

	public LazyDataModel<PlanillaContratista> getListaPlanillaContratista() {
		return listaPlanillaContratista;
	}

	public void setListaPlanillaContratista(LazyDataModel<PlanillaContratista> listaPlanillaContratista) {
		this.listaPlanillaContratista = listaPlanillaContratista;
	}

	public DataTable getDtPlanillaContratista() {
		return dtPlanillaContratista;
	}

	public void setDtPlanillaContratista(DataTable dtPlanillaContratista) {
		this.dtPlanillaContratista = dtPlanillaContratista;
	}

	/**
	 * Get del atributo dtCronogramaPlanillaContratista
	 * 
	 * @return el valor del atributo dtCronogramaPlanillaContratista
	 */
	public DataTable getDtCronogramaPlanillaContratista() {
		return dtCronogramaPlanillaContratista;
	}

	/**
	 * Set del atributo dtCronogramaPlanillaContratista
	 * 
	 * @param dtCronogramaPlanillaContratista
	 *            valor para asignar al atributo dtCronogramaPlanillaContratista
	 */
	public void setDtCronogramaPlanillaContratista(DataTable dtCronogramaPlanillaContratista) {
		this.dtCronogramaPlanillaContratista = dtCronogramaPlanillaContratista;
	}

	/**
	 * Get del atributo dtDetallePlanillaContratista
	 * 
	 * @return el valor del atributo dtDetallePlanillaContratista
	 */
	public DataTable getDtDetallePlanillaContratista() {
		return dtDetallePlanillaContratista;
	}

	/**
	 * Set del atributo dtDetallePlanillaContratista
	 * 
	 * @param dtDetallePlanillaContratista
	 *            valor para asignar al atributo dtDetallePlanillaContratista
	 */
	public void setDtDetallePlanillaContratista(DataTable dtDetallePlanillaContratista) {
		this.dtDetallePlanillaContratista = dtDetallePlanillaContratista;
	}

}
